package com.affectu.search.fetch.thread;

import java.util.Date;

import org.hibernate.Session;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;

import com.affectu.common.base.UtilBase;
import com.affectu.common.util.PersistanceUtil;
import com.affectu.news.News;

/**
 * Oct 11, 2008
 * 
 * @author daniel nathan
 */
public abstract class NewsThread extends UtilBase implements Runnable,
		IFetchBase<News> {

	private String url;

	private String subPagePattern;

	public NewsThread(String url, String subPagePattern) {
		this.url = url;
		this.subPagePattern = subPagePattern;
	}

	public void run() {
		this.spidePage();
	}

	public void spidePage() {
		this.log("Fetch news begin..." + url);

		try {
			Parser p = new Parser(url);
			p.setEncoding("gb2312");
			NodeList linkList = p.parse(new NodeClassFilter(LinkTag.class)); // 使用NodeClassFilter

			for (int i = 0; i < linkList.size(); i++) {// one level directory
				String newsLink = ((LinkTag) linkList.elementAt(i)).getLink();
				String newsName = ((LinkTag) linkList.elementAt(i)).getText();

				if (newsLink.indexOf(subPagePattern) != -1) {

					if (!this.containThisRecord(newsLink, newsName)) {
						this.saveObject(this.spideSubPage(newsLink));
					} else {
						this.log("already haved- url:" + url);// break;
					}
				}
			}

		} catch (Exception ex) {
			this.logAffectuException(ex, "取新闻异常:" + url);
		}

		this.log("Fetch news end..." + url);
	}

	public abstract News spideSubPage(String url);

	public boolean saveObject(News t) {
		lock.lock();
		boolean flag = false;
		Session em = PersistanceUtil.getInstance().getSession();
		try {
			t.setId(System.currentTimeMillis());
			t.setCreateDate(new Date());
			em.save(t);
			flag = true;
		} catch (Exception ex) {
			this.logAffectuException(ex, "存新闻异常");
		} finally {
			em.close();
			lock.unlock();
		}
		return flag;
	}

	public boolean containThisRecord(String link, String newsName) {
		return this.checkLink(link) || this.checkNewsName(newsName);
	}

	public boolean checkLink(String link) {
		boolean flag = false;
		Session em = PersistanceUtil.getInstance().getSession();
		try {
			Object ov = em.createSQLQuery(
					"select count(n.id) from News n where n.link=:link")
					.setParameter("link", link).uniqueResult();
			if (Integer.valueOf(ov.toString()).intValue() > 0) {
				flag = true;
			}
		} catch (Exception ex) {
			this.logAffectuException(ex, "检查link出错:" + link);
		} finally {
			em.close();
		}
		return flag;
	}

	public boolean checkNewsName(String name) {
		boolean flag = false;
		Session em = PersistanceUtil.getInstance().getSession();
		try {

			Object ov = em.createSQLQuery(
					"select count(n.id) from News n where n.name=:name")
					.setParameter("name", name).uniqueResult();
			if (Integer.valueOf(ov.toString()).intValue() > 0) {
				flag = true;
			}
		} catch (Exception ex) {
			this.logAffectuException(ex, "检查title出错:" + name);
		} finally {
			em.close();
		}
		return flag;
	}
}
